/**
 * 
 */
package mx.netbrain.bean;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;

import mx.netbrain.controller.FileDownloadController;
import mx.netbrain.controller.PropertiesController;
import mx.netbrain.controller.TreeController;
import mx.netbrain.dao.ProfileDao;
import mx.netbrain.dao.PropertiesRepositoriesDao;
import mx.netbrain.dao.TreeDao;
import mx.netbrain.dao.impl.ProfileDaoImpl;
import mx.netbrain.dao.impl.PropertiesRepositoriesDaoImpl;
import mx.netbrain.dao.impl.TreeDaoImpl;
import mx.netbrain.model.Profile;
import mx.netbrain.model.PropertiesRepositories;
import mx.netbrain.model.PropertiesRepositoriesValue;
import mx.netbrain.model.Tree;
import mx.netbrain.model.User;
import mx.netbrain.util.CreateFolderUtil;
import mx.netbrain.util.FileUploadUtil;
import mx.netbrain.util.FolderDataUtil;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.TreeNode;
import org.primefaces.model.UploadedFile;

/**
 * @author julian
 * 
 */

public class TreeBean implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -1746748603239885336L;
	private User user = new User();
	private Tree tree = new Tree();
	private TreeDao treeDao = new TreeDaoImpl();
	private ProfileDao profileDao = new ProfileDaoImpl();
	private Profile profile;
	private TreeNode rootNode;
	private TreeNode selectedNode;
	private FolderDataUtil mediumFolderModel;
	private Tree[] selectedTrees;
	private String nameFolder;
	private UploadedFile file;
	private UploadedFile fileProperties;
	private List<PropertiesRepositories> listProperties;
	private String[] props;
	private StreamedContent fileDownload;

	@SuppressWarnings("unused")
	public TreeBean() {
		FacesContext session = FacesContext.getCurrentInstance();
		user = (User) session.getExternalContext().getSessionMap()
				.get("userSession");
		rootNode = new DefaultTreeNode("ROOT", null);
		List<Tree> listTree = treeDao.listAllUser(user);
		for (Tree treeFor : listTree) {
			TreeNode t1 = TreeController.createTree(treeFor, rootNode, user);
		}
	}

	public void onNodeSelect(NodeSelectEvent event) {
		tree = (Tree) event.getTreeNode().getData();
		profile = profileDao.findByPerfil(user.getId(), tree);
		List<Tree> listFolder = new ArrayList<Tree>();
		listFolder = treeDao.listNodeFolder(tree.getId(), user);
		mediumFolderModel = new FolderDataUtil(listFolder);
	}

	public void selectedRow() {
		if (selectedTrees.length == 0) {
			tree = new Tree();
			FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR,
					"No se selecciono ningun elemento", "");
			addMessage(message);
		} else {
			for (int i = 0; i < selectedTrees.length; i++) {
				prepareTree(selectedTrees[i].getId());
			}
		}
	}

	public void prepareTree(Long id) {
		tree = new Tree();
		tree = treeDao.findById(id);
	}

	public void selectedRowProperties() {
		if (selectedTrees.length == 1) {
			for (int i = 0; i < selectedTrees.length; i++) {
				if (selectedTrees[i].getType().equals("Documento")) {
					prepareTreeProperties(selectedTrees[i].getId());
				}
			}
		} else {
			FacesMessage message = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "Error",
					"Favor de seleccionar solo un elemento");
			addMessage(message);
		}
	}

	public void selectedRowPropertiesFile(FileUploadEvent event)
			throws IOException {
		fileProperties = event.getFile();
		FileUploadUtil.uploadFileTmp(fileProperties, selectedTrees);
		FacesMessage message = new FacesMessage("El archivo: ", event.getFile()
				.getFileName() + " se cargo correctamente.");
		addMessage(message);
	}

	public void prepareTreeProperties(Long id) {
		tree = new Tree();
		tree = treeDao.findById(id);
		PropertiesRepositoriesDao propertiesRepositoriesDao = new PropertiesRepositoriesDaoImpl();
		listProperties = propertiesRepositoriesDao.listForRepositories(tree
				.getRepositories());
		props = new String[listProperties.size()];
		for (int i = 0; i < listProperties.size(); i++) {
			PropertiesRepositoriesValue propsValue = new PropertiesRepositoriesValue();
			propsValue = propertiesRepositoriesDao.findPropertieValue(
					listProperties.get(i).getRepositories().getId(),
					tree.getId(), listProperties.get(i).getId());
			props[i] = propsValue.getValue();
		}
	}

	public void prepareTreeDownload(Long id) {
		tree = new Tree();
		tree = treeDao.findById(id);
		fileDownload = FileDownloadController.fileDownloadController(tree);
	}

	public void treeDownload() {
		TreeController.checkinFile(tree, user);
	}

	@SuppressWarnings("unused")
	public void mediumFolder() {
		List<Tree> listFolder = new ArrayList<Tree>();
		listFolder = treeDao.listNodeFolder(tree.getId(), user);
		mediumFolderModel = new FolderDataUtil(listFolder);
		rootNode = new DefaultTreeNode("ROOT", null);
		List<Tree> listTree = treeDao.listAllUser(user);
		for (Tree treeFor : listTree) {
			TreeNode t1 = TreeController.createTree(treeFor, rootNode, user);
		}
		tree = new Tree();
	}

	public void newFolder() {
		CreateFolderUtil.createFolderDataBase(tree, nameFolder, user,
				profile.getId());
		mediumFolder();
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
				"Se creo una nueva carpeta.", "");
		addMessage(message);
		nameFolder = new String();
		tree = new Tree();
	}

	public void editFolder() {
		if (tree.getType().equals("Carpeta")) {
			CreateFolderUtil.editFolderDataBase(tree);
			mediumFolder();
		} else {
			FacesMessage message = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "Error", tree.getName()
							+ ": No es una carpeta");
			addMessage(message);
		}
	}

	public void deleteFolder() {
		if (tree.getType().equals("Carpeta")) {
			CreateFolderUtil.deleteFolderDataBase(tree);
			mediumFolder();
		} else {
			FacesMessage message = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "Error", tree.getName()
							+ ": No es una carpeta");
			addMessage(message);
		}
	}

	public void fileUpload(FileUploadEvent event) {
		file = event.getFile();
		FileUploadUtil.uploadValidate(file, tree, user, profile.getId());
		mediumFolder();
	}

	public void editFile() {
		FileUploadUtil.editFile(tree);
		mediumFolder();
	}

	public void saveProperties() {
		PropertiesController.saveProperties(props, listProperties, tree);
		FacesMessage message = new FacesMessage(FacesMessage.FACES_MESSAGES,
				"Las propiedades se guardaron correctamente.");
		addMessage(message);
		cancelProperties();
	}

	public void cancelProperties() {
		tree = new Tree();
		listProperties = new ArrayList<PropertiesRepositories>();
		props = null;
	}

	public TreeNode getRootNode() {
		return rootNode;
	}

	public void setRootNode(TreeNode rootNode) {
		this.rootNode = rootNode;
	}

	public TreeNode getSelectedNode() {
		return selectedNode;
	}

	public void setSelectedNode(TreeNode selectedNode) {
		this.selectedNode = selectedNode;
	}

	public Tree getTree() {
		return tree;
	}

	public void setTree(Tree tree) {
		this.tree = tree;
	}

	public Profile getProfile() {
		return profile;
	}

	public void setProfile(Profile profile) {
		this.profile = profile;
	}

	public FolderDataUtil getMediumFolderModel() {
		return mediumFolderModel;
	}

	public void setMediumFolderModel(FolderDataUtil mediumFolderModel) {
		this.mediumFolderModel = mediumFolderModel;
	}

	public Tree[] getSelectedTrees() {
		return selectedTrees;
	}

	public void setSelectedTrees(Tree[] selectedTrees) {
		this.selectedTrees = selectedTrees;
	}

	public String getNameFolder() {
		return nameFolder;
	}

	public void setNameFolder(String nameFolder) {
		this.nameFolder = nameFolder;
	}

	public UploadedFile getFileProperties() {
		return fileProperties;
	}

	public List<PropertiesRepositories> getListProperties() {
		return listProperties;
	}

	public void setListProperties(List<PropertiesRepositories> listProperties) {
		this.listProperties = listProperties;
	}

	public String[] getProps() {
		return props;
	}

	public void setProps(String[] props) {
		this.props = props;
	}

	public StreamedContent getFileDownload() {
		return fileDownload;
	}

	public void setFileDownload(StreamedContent fileDownload) {
		this.fileDownload = fileDownload;
	}

	private void addMessage(FacesMessage message) {
		FacesContext.getCurrentInstance().addMessage(null, message);
	}

}